#include "dsproxy_command_handler.h"
#include <boost/bind.hpp>
#include "IObject/ITCPClient.h"
#include "IObject/Protocol.h"
#include <stdio.h>
#include "boost/thread/lock_types.hpp"

namespace DSProxy
{
	command_handler::command_handler()
	{
		m_timerRemoteKeepAlive = 0;
		m_pCSCodec = NULL;
		m_index = 0;
	}

	command_handler::~command_handler()
	{
		if (m_pCSCodec != NULL)
		{
			delete m_pCSCodec;
			m_pCSCodec = NULL;
		}
	}

	void command_handler::Init(const char* pszModuleName, IServerObject * pServerObj)
	{
		m_pCSCodec = new CSCodec();

		std::string strKeys = "plugins.";
		strKeys += pszModuleName;

		m_pServerObject = pServerObj;
		IPropertyParser* pParser = m_pServerObject->getPropertyParser();
		
		m_ServerToken = pParser->getString(NULL, "base.server.token");

		NodeToken rootNode = pParser->getRoot();

		std::string keyTemp = strKeys;

		keyTemp = strKeys + ".args.arg1";
		std::string strArg1 = pParser->getString(rootNode, keyTemp.c_str());

		keyTemp = strKeys + ".args.arg2";
		std::string strArg2 = pParser->getString(rootNode, keyTemp.c_str());

		std::cout << strKeys << " load success !!!!!!" << std::endl;

		m_pServerObject->registerCmdHandler(1, (void*)this, 
			boost::bind(&command_handler::OnClientConnected, this, _1, _2, _3, _4));

		m_pServerObject->registerCmdHandler(2, (void*)this, 
			boost::bind(&command_handler::OnClientDisconnected, this, _1, _2, _3, _4));

		m_pServerObject->registerCmdHandler(100, (void*)this,
			boost::bind(&command_handler::OnMessage_100, this, _1, _2, _3, _4));

		ITCPClient*  pClient = m_pServerObject->getTCPClient();
		if (pClient != NULL)
		{
			MessageHandler handler = boost::bind(&command_handler::OnRemoteMessage, this, _1, _2, _3, _4);
			pClient->Connect(100, "192.168.8.191", 10110, m_pCSCodec, handler);
		}

		m_timerRemoteKeepAlive = m_pServerObject->getTimerManager()->schedule(m_timerRemoteKeepAlive,
			10000, boost::bind(&command_handler::keepalive, this, _1));
	}

	void command_handler::Fina()
	{
		m_pServerObject->getTimerManager()->cancel(m_timerRemoteKeepAlive);
	}

	void command_handler::OnClientConnected(SocketID socketID, int cmd, 
		const void * pBuffer, uint32_t size)
	{

	}

	void command_handler::OnClientDisconnected(SocketID socketID, int cmd,
		const void * pBuffer, uint32_t size)
	{
		RemoveClient(socketID);
	}

	void command_handler::OnRemoteMessage(SocketID socketID, int cmd,
											const void * pBuffer, uint32_t size)
	{
		if (cmd == Framework::SYSTEM_SOCKET_REMOTE_CONNECTED)
		{
			login(socketID);
		}
		else if (cmd == Framework::SYSTEM_SOCKET_REMOTE_DISCONNECTED)
		{
			CloseClientByRemoteID(socketID);
		}
		else if (cmd == Framework::SYSTEM_SOCKET_REMOTE_CONNECT_ERROR)
		{
		}
		else
		{
			
		}
	}

	void command_handler::login(SocketID socketID)
	{
// 		char szBuffer[256];
// 		sprintf(szBuffer, "%s_%d", m_ServerToken.c_str(), socketID);
// 
// 
// 		S2SPacketHead head;
// 		head.session_id = 0;
// 		head.req_id = 1;
// 		head.protocol_id = Framework::S2S_SERVER_ID_NTF;
// 		head.body_len = strlen(szBuffer) + 2;
// 
// 		ByteBuffer writer;
// 		head.encode(writer);
// 
// 		writer << head.body_len;
// 		writer.append(szBuffer, head.body_len);
// 
// 		ITCPClient*  pClient = m_pServerObject->getTCPClient();
// 		if (pClient != NULL)
// 		{
// 			pClient->AsyncSend(socketID, (const char*)writer.contents(), writer.size());
// 		}
	}

	void command_handler::keepalive(TimerID id)
	{
// 		S2SPacketHead head;
// 		head.session_id = 0;
// 		head.req_id = 1;
// 		head.protocol_id = Framework::S2S_KEEP_LIVE;
// 		head.body_len = 0;
// 
// 		ByteBuffer buffer;
// 		buffer.append(head);
// 
// 		ITCPClient*  pClient = m_pServerObject->getTCPClient();
// 		if (pClient != NULL)
// 		{
// 			for (size_t n = 0; n < m_RemoteServerIDS.size(); ++n)
// 			{
// 				if (m_RemoteServerIDS[n].second)
// 				{
// 					pClient->AsyncSend(m_RemoteServerIDS[n].first, (const char*)buffer.contents(), buffer.size());
// 				}				
// 			}			
// 		}
// 
// 		m_timerRemoteKeepAlive = m_pServerObject->getTimerManager()->schedule(m_timerRemoteKeepAlive,
// 			10000, boost::bind(&command_handler::keepalive, this, _1));
	}

	void command_handler::OnMessage_100(SocketID socketID, int cmd, const void * pBuffer, uint32_t size)
	{
		std::string strValues = "123445666";
		m_pServerObject->getSessionManager()->AsyncSend(socketID, strValues.c_str(), strValues.length(), CONTENT_BINARY);
	}

	SocketID command_handler::GetValidRemoteServer()
	{
		SocketID sID = 0;

		ITCPClient*  pClient = m_pServerObject->getTCPClient();
		if (pClient != NULL)
		{
			
		}

		for (int idx = m_index; idx < (int)m_RemoteServerIDS.size(); ++idx)
		{
			if (m_RemoteServerIDS[idx].second)
			{
				sID = m_RemoteServerIDS[idx].first;
			}
		}

		if (sID <= 0)
		{
			for (int idx = 0; idx < m_index && idx < (int)m_RemoteServerIDS.size(); ++idx)
			{
				if (m_RemoteServerIDS[idx].second)
				{
					sID = m_RemoteServerIDS[idx].first;
				}
			}
		}
		m_index++;

		if (m_index >= (int)m_RemoteServerIDS.size())
		{
			m_index = 0;
		}

		return sID;
	}

	void command_handler::RemoveClient(SocketID	socketID)
	{
		boost::unique_lock<boost::shared_mutex> lock(m_rw_lock_clients);
		for (std::list< std::pair<SocketID, SocketID> >::iterator iter = m_SocketPair.begin();
			iter != m_SocketPair.end(); ++iter)
		{
			if ((*iter).first == socketID)
			{
				m_SocketPair.erase(iter);
				break;
			}
		}
	}

	void command_handler::CloseClientByRemoteID(SocketID	remoteID)
	{
		boost::unique_lock<boost::shared_mutex> lock(m_rw_lock_clients);
		for (std::list< std::pair<SocketID, SocketID> >::iterator iter = m_SocketPair.begin();
			iter != m_SocketPair.end();)
		{
			if ((*iter).second == remoteID)
			{
				m_pServerObject->getSessionManager()->Close((*iter).first);
				iter = m_SocketPair.erase(iter);
			}
			else
			{
				++iter;
			}
		}
	}

}
